#ifndef __DATABASE_H__
#define __DATABASE_H__

#include <vector>
#include <string>
#include <fstream>
#include "pthread.h"
#include "car.h"

#define FAILED 0
#define INVALID 2
#define REPEAT 3
#define WARNING 4
#define SUCCESS 1

using namespace std;

class Database
{
  private:
    vector <Car> cars;
    pthread_mutex_t mutex;
    string filename;
    string name;
    string state;
    string preCode;

  public:
    Database()
    {
      filename = "";
      name = "";
      state = "";
      preCode = "";
    }

    Database(string filename, string name)
    {
        this->filename = filename;
        this->name = name;
	if( name == "AL")
	{
	  preCode = "01";
	  state = "Alabama";
	}
	else if( name == "AK")
	{
	  preCode = "02";
	  state = "Alaska";
	}
	else if( name == "AZ")
        {
	  preCode = "03";
	  state = "Arizona";
	}
	else if( name == "AR")
	{
	  preCode = "04";
	  state = "Arkansas";
	}
	else if( name == "CA")
	{
	  preCode = "05";
	  state = "California";
	}	
	else if( name == "CO")
	{
	  preCode = "06";
	  state = "Colorado";
	}
	else if( name == "CT")
	{
	  preCode = "07";
	  state = "Connecticut";
	}
	else if( name == "DE")
	{
	  preCode = "08";
	  state = "Delaware";
	}
	else if( name == "DC")
	{
	  preCode = "09";
	  state = "Disctrict of Columbia";
	}
	else if( name == "FL")
	{
	  preCode = "10";
	  state = "Florida";
	}
	else if( name == "GA")
	{
	  preCode = "11";
	  state = "Georgia";
	}
	else if( name == "HI")
	{
	  preCode = "12";
	  state = "Hawaii";
	}
	else if( name == "ID")
	{
	  preCode = "13";
	  state = "Idaho";
	}
	else if( name == "IL")
	{
	  preCode = "14";
	  state = "Illinois";
	}
	else if( name == "IN")
	{
	  preCode = "15";
	  state = "Indiana";
	}
	else if( name == "IA")
	{
	  preCode = "16";
	  state = "Iowa";
	}
	else if( name == "KS")
	{
	  preCode = "17";
	  state = "Kansas";
	}
	else if( name == "KY")
	{
	  preCode = "18";
	  state = "Kentucky";
	}
	else if( name == "LA")
	{
	  preCode = "19";
	  state = "Louisiana";
	}
	else if( name == "ME")
	{
	  preCode = "20";
	  state = "Maine";
	}
	else if( name == "MD")
	{
	  preCode = "21";
	  state = "Maryland";
	}
	else if( name == "MA")
	{
	  preCode = "22";
	  state = "Massachusetts";
	}
	else if( name == "MI")
	{
	  preCode = "23";
	  state = "Michigan";
	}
	else if( name == "MN")
	{
	  preCode = "24";
	  state = "Minnesota";
	}
	else if( name == "MS")
	{
	  preCode = "25";
	  state = "Mississippi";
	}
	else if( name == "MO")
	{
	  preCode = "26";
	  state = "Missouri";
	}
	else if( name == "MT")
	{
	  preCode = "27";
	  state = "Montana";
	}
	else if( name == "NE")
	{
	  preCode = "28";
	  state = "Nebraska";
	}
	else if( name == "NV")
	{
	  preCode = "29";
	  state = "Nevada";
	}
	else if( name == "NH")
        {
	  preCode = "30";
	  state = "New Hampshire";
	}
	else if( name == "NJ")
	{
	  preCode = "31";
	  state = "New Jersey";
	}
	else if( name == "NM")
	{
	  preCode = "32";
	  state = "New Mexico";
	}
	else if( name == "NY")
	{
	  preCode = "33";
	  state = "New York";
	}
	else if( name == "NC")
	{
	  preCode = "34";
	  state = "North Carolina";
	}
	else if( name == "ND")
	{
	  preCode = "35";
	  state = "North Dakota";
	}
	else if( name == "OH")
	{
	  preCode = "36";
	  state = "Ohio";
	}
	else if( name == "OK")
	{
	  preCode = "37";
	  state = "Oklahoma";
	}
	else if( name == "OR")
	{
	  preCode = "38";
	  state = "Oregon";
	}
	else if( name == "PA")
	{
	  preCode = "39";
	  state = "Pennsylvania";
	}
	else if( name == "RI")
	{
	  preCode = "40";
	  state = "Rhode Island";
	}
	else if( name == "SC")
	{
	  preCode = "41";
	  state = "South Carolina";
	}
	else if( name == "SD")
	{
	  preCode = "42";
	  state = "South Dakota";
	}
	else if( name == "TN")
	{
	  preCode = "43";
	  state = "Tennessee";
	}
	else if( name == "TX")
	{
	  preCode = "44";
	  state = "Texas";
	}
	else if( name == "UT")
	{
	  preCode = "45";
	  state = "Utah";
	}
	else if( name == "VT")
	{
	  preCode = "46";
	  state = "Vermont";
	}
	else if( name == "VA")
	{
	  preCode = "47";
	  state = "Virginia";
	}
	else if( name == "WA")
	{
	  preCode = "48";
	  state = "Washington";
	}
	else if( name == "WV")
	{
	  preCode = "49";
	  state = "West Virginia";
	}
	else if( name == "WI")
	{
	  preCode = "50";
	  state = "Wisconsin";
	}
	else if( name == "WY")
	{
	  preCode = "51";
	  state = "Wyoming";
	}
    }

    pthread_mutex_t* getMutex()
    {
        return &mutex;
    }

    string getName()
    {
        return name;
    }

    string getManu(int car)
    {
      return cars[car].manufacturer;
    }

    string getBrand(int car)
    {
      return cars[car].brand;
    }

    string getPreCode()
    {
        return preCode;
    }

    string getState()
    {
      return state;
    }


    void mutexLock()
    {
      pthread_mutex_lock(&mutex);
    }

    void mutexUnlock()
    {
      pthread_mutex_unlock(&mutex);
    }

    int insert(string code)
    {
        if(code.length() != 6)
	{
	    return INVALID; 
	}

	string db, manu, model;
	
	db = code.substr(0,2);
	manu = code.substr(2,2);
	model = code.substr(4,2);

	if(db > "51" || db < "00")
	  return INVALID;

	if(manu > "07" || manu < "01" || model < "01")
	  return INVALID;

	if(manu == "01")
	{
	  manu = "Ford";
	  if(model > "10")
	    return INVALID;
	  else if(model == "01")
	    model = "Aspire";
	  else if(model == "02")
	    model = "Contour";
	  else if(model == "03")
	    model = "CrownVictoria";
	  else if(model == "04")
	    model = "Escort";
	  else if(model == "05")
	    model = "Festiva";
	  else if(model == "06")
	    model = "Mustang";
	  else if(model == "07")
	    model = "Probe";
	  else if(model == "08")
	    model = "Taurus";
	  else if(model == "09")
	    model = "Tempo";
	  else if(model == "10")
	    model = "Thunderbird";
	}
	else if(manu == "02")
	{
	  manu = "Toyota";
	  if(model > "15")
	    return INVALID;
	  else if(model == "01")
	    model = "4Runner";
	  else if(model == "02")
	    model = "Avalon";
	  else if(model == "03")
	    model = "Camry";
	  else if(model == "04")
	    model = "Celica";
	  else if(model == "05")
	    model = "Corolla";
	  else if(model == "06")
	    model = "Corona";
	  else if(model == "07")
	    model = "Cressida";
	  else if(model == "08")
	    model = "LandCruiser";
	  else if(model == "09")
	    model = "MR2";
	  else if(model == "10")
	    model = "Paseo";
	  else if(model == "11")
	    model = "Previa";
	  else if(model == "12")
	    model = "RAV4";
	  else if(model == "13")
	    model = "Supra";
	  else if(model == "14")
	    model = "Tacoma";
	  else if(model == "15")
	    model = "Tercel";
	}
	else if(manu == "03")
	{
	  manu = "Honda";
	  if(model > "06")
	    return INVALID;
	  else if(model == "01")
	    model = "Accord";
	  else if(model == "02")
	    model = "Civic";
	  else if(model == "03")
	    model = "CR-V";
	  else if(model == "04")
	    model = "Odyssey";
	  else if(model == "05")
	    model = "Passport";
	  else if(model == "06")
	    model = "Prelude"; 
	}
	else if(manu == "04")
	{
	  manu = "Dodge";
	  if(model > "13")
	    return INVALID;
	  else if(model == "01")
	    model = "Avenger";
	  else if(model == "02")
	    model = "Colt";
	  else if(model == "03")
	    model = "Daytona";
	  else if(model == "04")
	    model = "Durango";
	  else if(model == "05")
	    model = "Dynasty";
	  else if(model == "06")
	    model = "Intrepid";
	  else if(model == "07")
	    model = "Lancer";
	  else if(model == "08")
	    model = "Neon";
	  else if(model == "09")
	    model = "Omni";
	  else if(model == "10")
	    model = "Shawdow";
	  else if(model == "11")
	    model = "Spirit";
	  else if(model == "12")
	    model = "Stealth";
	  else if(model == "13")
	    model = "Stratus";
	}
	else if(manu == "05")
	{
	  manu = "Chrysler";
	  if(model > "08")
	    return INVALID;
	  else if(model == "01")
	    model = "Cirrus";
	  else if(model == "02")
	    model = "Concorde";
	  else if(model == "03")
	    model = "Imperial";
	  else if(model == "04")
	    model = "Laser";
	  else if(model == "05")
	    model = "Lebaron";
	  else if(model == "06")
	    model = "NewYorker";
	  else if(model == "07")
	    model = "Sebring";
	  else if(model == "08")
	    model = "TownandCountry";
	}
	else if(manu == "06")
	{
	  manu = "Buick";
	  if(model > "08")
	    return INVALID;
	  else if(model == "01")
	    model = "Century";
	  else if(model == "02")
	    model = "GrandNational";
	  else if(model == "03")
	    model = "LeSabre";
	  else if(model == "04")
	    model = "ParkAvenue";
	  else if(model == "05")
	    model = "Reqal";
	  else if(model == "06")
	    model = "Riviera";
	  else if(model == "07")
	    model = "Roadmaster";
	  else if(model == "08")
	    model = "Skylark";
	}
	else if(manu == "07")
	{
	  manu = "Mazda";
	  if(model > "11")
	    return INVALID;
	  else if(model == "01")
	    model = "323";
	  else if(model == "02")
	    model = "626";
	  else if(model == "03")
	    model = "929";
	  else if(model == "04")
	    model = "Miata";
	  else if(model == "05")
	    model = "Millenia";
	  else if(model == "06")
	    model = "MX-3";
	  else if(model == "07")
	    model = "MX-6";
	  else if(model == "08")
	    model = "Navajo";
	  else if(model == "09")
	    model = "Proteqe";
	  else if(model == "10")
	    model = "RX-4";
	  else if(model == "11")
	    model = "RX-7";
	}
    
	for(unsigned int i = 0; i < cars.size(); ++i)
	{
	  if(cars[i].salesCode == code)
	    return REPEAT;
	}

	Car temp(code, manu, model);
	cars.push_back(temp);
	return SUCCESS;
	
    }

    void save()
    {
  
        ofstream outfile;
        outfile.open(filename.c_str());

        outfile << cars.size() << endl << state << endl << endl;

        for(unsigned int i = 0; i < cars.size(); ++i)
        {
            outfile << cars[i].salesCode << " " << cars[i].manufacturer << " "
                    << cars[i].brand     << " " << cars[i].year << " "
                    << cars[i].num << endl << endl;
        }
	outfile.close();

    }

    int load()
    {
        ifstream infile;
        infile.open(filename.c_str());

	if(!infile.is_open())
	  return FAILED;


        int amount = 0;

        infile >> amount >> state;
        string salesCode = "";
        string manufacturer = "";
        string brand = "";
        int year = 0;
        int num = 0;

        for(int i = 0; i < amount; ++i)
        {
            infile >> salesCode >> manufacturer >> brand >> year >> num;
            cars.push_back(Car(salesCode, manufacturer, brand, year,
			       num));
        }
        infile.close();
	return SUCCESS;
    }

    int del(string code)
    {
        if(code.length() != 6)
	{
	    return INVALID; 
	}

	string db, manu, model;
	
	db = code.substr(0,2);
	manu = code.substr(2,2);
	model = code.substr(4,2);

	if(db > "51" || db < "00")
	  return INVALID;

	if(manu > "07" || manu < "01" || model < "01")
	  return INVALID;

	for(unsigned int i = 0; i < cars.size(); ++i)
	{
	  if(cars[i].salesCode == code)
	  {
	    cars.erase(cars.begin() + i);
	    return SUCCESS;
	  }
	   
	}

	return FAILED;
    }

    int buy(string code, int amount)
    {
      if(code.length() != 6)
	{
	    return INVALID; 
	}

	string db, manu, model;
	
	db = code.substr(0,2);
	manu = code.substr(2,2);
	model = code.substr(4,2);

	if(db > "51" || db < "00")
	  return INVALID;

	if(manu > "07" || manu < "01" || model < "01")
	  return INVALID;

	for(unsigned int i = 0; i < cars.size(); ++i)
	{
	  if(cars[i].salesCode == code)
	  {
	    cars[i].num += amount;
	    return SUCCESS;
	  }
	   
	}

	return FAILED;
    }

    void print()
    {
      for(unsigned int i = 0; i < cars.size(); ++i)
      {
	cout << cars[i].salesCode << " : " << state << " : " 
	     << cars[i].manufacturer << " : "
	     << cars[i].brand << " : " << cars[i].num << endl;
      }
    }
     
    int printo(string code)
    {
      if(code.size() == 2)
      {
	print();
	return SUCCESS;
      }
      else if(code.size() == 4)
      {
	for(unsigned int i = 0; i < cars.size(); ++i)
	{
	  if(cars[i].salesCode.substr(2,2) == code.substr(2,2))
	  {
	    cout << cars[i].salesCode << " : " << state << " : " 
		 << cars[i].manufacturer << " : "
		 << cars[i].brand << " : " << cars[i].num << endl;
	  }
	}
	return SUCCESS;
      }
      else
      {
	for(unsigned int i = 0; i < cars.size(); ++i)
	{
	  if(cars[i].salesCode == code)
	  {
	    cout << cars[i].salesCode << " : " << state << " : " 
		 << cars[i].manufacturer << " : "
		 << cars[i].brand << " : " << cars[i].num << endl;
	    return SUCCESS;
	  }
	}
	return FAILED;
      }
    }

    int sell(string code, int amount)
    {
      if(code.length() != 6)
	{
	    return INVALID; 
	}

	string db, manu, model;
	
	db = code.substr(0,2);
	manu = code.substr(2,2);
	model = code.substr(4,2);

	if(db > "51" || db < "00")
	  return INVALID;

	if(manu > "07" || manu < "01" || model < "01")
	  return INVALID;

	for(unsigned int i = 0; i < cars.size(); ++i)
	{
	  if(cars[i].salesCode == code)
	  {
	    int temp = cars[i].num;
	    cars[i].num -= amount;
	    if(temp < amount)
	    {
	      cars[i].num = 0;
	      return WARNING;
	    }
	    return SUCCESS;
	  }
	   
	}

	return FAILED;
    }
     

};

#endif
